package io.bdmc.common.aspect;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import com.baomidou.mybatisplus.extension.activerecord.Model;

import org.apache.shiro.SecurityUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import io.bdmc.common.annotation.SysLogger1;
import io.bdmc.common.utils.CompareObjectUtils;
import io.bdmc.common.utils.Constant.ModifyName;
import io.bdmc.common.utils.HttpContextUtils;
import io.bdmc.common.utils.IPUtils;
import io.bdmc.modules.sys.entity.SysLog;
import io.bdmc.modules.sys.entity.SysUser;

/**
 * 系统日志，切面处理类
 * 
 * @author huang lu
 * @email hlkyo@qq.com
 * @date 2017年3月8日 上午11:07:35
 */
@Aspect
@Component
public class SysLogAspect {
	@Pointcut("@annotation(io.bdmc.common.annotation.SysLogger1)")
	public void logPointCut() {

	}

	@Around("logPointCut()")
	public Object around(ProceedingJoinPoint point) throws Throwable {
		long beginTime = System.currentTimeMillis();
		String logStr = "";
		MethodSignature signature = (MethodSignature) point.getSignature();
		Method method = signature.getMethod();
		SysLogger1 syslogger = method.getAnnotation(SysLogger1.class);
		if (syslogger != null && point.getArgs()!=null&&point.getArgs().length>0 ) {
			Object obj = point.getArgs()[0];
			if (syslogger.operationType().equals(ModifyName.UPDATE)) {
				if (obj instanceof Model) {
					Model<?> m = (Model<?>) obj;
					Object dbObject = m.selectById();
					logStr = CompareObjectUtils.log(dbObject, m, syslogger.operationType());
				}
			} else if (syslogger.operationType().equals(ModifyName.ADD)) {
				logStr = CompareObjectUtils.log(obj, null, syslogger.operationType());
			} else if (syslogger.operationType().equals(ModifyName.DELETE)) {

				Class<?> entityCls = syslogger.entityType();
				Object obj1 = entityCls.newInstance();
				if (obj1 instanceof Model) {
					Model<?> m = (Model<?>) obj1;
					Serializable id = 0;
					if (obj instanceof Long) {
						id = (Long) obj;
					} else if (obj instanceof Integer) {
						id = (Integer) obj;
					}
					Object dbObject = m.selectById(id);
					logStr = CompareObjectUtils.log(dbObject, null, syslogger.operationType());
				}

			}

		}
		// 请求的方法名
		String methodName = method.getName();
		// 执行方法
		Object result = point.proceed();
		// 保存日志,获取 执行时长(毫秒)
		long time = System.currentTimeMillis() - beginTime;
		saveSysLog(syslogger.value(), methodName, logStr, time);
		return result;
	}

	private void saveSysLog(String operation, String methodName, String logStr, long time) {
		SysLog sysLog = new SysLog();
		sysLog.setOperation(operation);
		sysLog.setMethod(methodName);
		// 获取request
		HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
		// 设置IP地址
		sysLog.setIp(IPUtils.getIpAddr(request));
		sysLog.setParams(logStr);
		// 用户名
		String username = ((SysUser) SecurityUtils.getSubject().getPrincipal()).getUsername();
		sysLog.setUsername(username);

		sysLog.setTime(time);
		sysLog.setCreateDate(new Date());
		// 保存系统日志
		sysLog.insert();
	}

}
